package cn.lingyangwl.agile.dynamic.client.wx;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceHttpClientImpl;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceJoddHttpImpl;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceOkHttpImpl;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.lingyangwl.agile.dynamic.client.AbstractClientProcess;
import cn.lingyangwl.agile.dynamic.client.DynamicClient;
import cn.lingyangwl.agile.model.enums.ConfigDefineEnum;
import cn.lingyangwl.agile.model.module.config.param.WxMaParam;
import cn.lingyangwl.framework.core.utils.spring.SpringUtils;
import cn.lingyangwl.framework.tool.core.StringUtils;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import com.alibaba.fastjson2.JSON;
import com.binarywang.spring.starter.wxjava.miniapp.enums.HttpClientType;
import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Component;

/**
 * 可以通过配置文件动态更新
 *
 * @author shenguangyang
 */
@Slf4j
@Data
@Component
@ConditionalOnClass(WxMaService.class)
@EqualsAndHashCode(callSuper = true)
public class WxMaDynamicConfig extends AbstractClientProcess {

    /**
     * 获取一个实例
     *
     * @param paramConfig json格式参数
     */
    @Override
    public DynamicClient createClient(String tenantId, String paramConfig) {
        log.info("refresh {} config", WxMaDynamicConfig.class.getName());
        if (StringUtils.isEmpty(paramConfig)) {
            throw new BizException("微信小程序配置参数不能为空");
        }
        WxMaWrapClient client = new WxMaWrapClient();
        WxMaParam param = JSON.parseObject(paramConfig, WxMaParam.class);
        WxMaProperties newProperties = new WxMaProperties();
        newProperties.setToken(param.getToken());
        newProperties.setAesKey(param.getEncodingAesKey());
        newProperties.setAppid(param.getAppId());
        newProperties.setSecret(param.getAppSecret());
        client.setWxMaProperties(newProperties);

        // 这里读取自动配置的值
        WxMaProperties properties = SpringUtils.getBean(WxMaProperties.class);
        WxMaProperties.ConfigStorage configStorage = properties.getConfigStorage();

        // 初始哈存储配置
        WxMaProperties.ConfigStorage currentConfigStorage = client.getWxMaProperties().getConfigStorage();
        currentConfigStorage.setType(configStorage.getType());
        currentConfigStorage.setHttpClientType(configStorage.getHttpClientType());
        currentConfigStorage.setHttpProxyHost(configStorage.getHttpProxyHost());
        currentConfigStorage.setMaxRetryTimes(configStorage.getMaxRetryTimes());
        currentConfigStorage.setHttpProxyPassword(configStorage.getHttpProxyPassword());
        currentConfigStorage.setKeyPrefix(configStorage.getKeyPrefix());
        currentConfigStorage.setRetrySleepMillis(configStorage.getRetrySleepMillis());

        // 覆盖token
        client.getWxMaProperties().setToken(properties.getToken());
        client.getWxMaProperties().setMsgDataFormat("JSON");

        WxMaInRedisTemplateConfigStorageConfiguration storageConfiguration = new WxMaInRedisTemplateConfigStorageConfiguration(client.getWxMaProperties());
        WxMaConfig wxMaConfig = storageConfiguration.wxMaConfig();

        HttpClientType httpClientType = client.getWxMaProperties().getConfigStorage().getHttpClientType();
        switch (httpClientType) {
            case OkHttp:
                client.setWxMaService(new WxMaServiceOkHttpImpl());
                break;
            case JoddHttp:
                client.setWxMaService(new WxMaServiceJoddHttpImpl());
                break;
            case HttpClient:
                client.setWxMaService(new WxMaServiceHttpClientImpl());
                break;
            default:
                client.setWxMaService(new WxMaServiceImpl());
        }
        client.getWxMaService().setWxMaConfig(wxMaConfig);
        return client;
    }

    @Override
    public ConfigDefineEnum configDefine() {
        return ConfigDefineEnum.WX_MA;
    }

}
